/*
 * cBarril.cpp
 *
 *  Created on: Nov 9, 2014
 *      Author: root
 */

#include "cBarril.h"
#include "../objetosGrilla.h"
#include "../manejadorGrilla.h"
#include "../personajes/cMono.h"
#include "../clasesAuxiliares/SocketCommunication.h"
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <iostream>
#include "../clasesAuxiliares/envioAlCliente.h"


const int GRILLA_WIDTH = 64;
const int GRILLA_HEIGHT = 48;

const int IZQUIERDA = 0;
const int DERECHA = 1;
const int SUBIENDO_ESCALERA = 2;
const int BAJANDO_ESCALERA = 3;
const int BUSCANDO_ESCALERA_INICIAL = 4;
const int SALTANDO_IZQUERDA = 5;
const int SALTANDO_DERECHA = 6;

const int ESCALERA_INICIAL_1 = 27;
const int ESCALERA_INICIAL_2 = 37;



cBarril::cBarril(){
	this->fin =  true;
	this->x = 0;
	this->y = 0;
	this->height = 2;
	this->witdh = 2;
}

cBarril::~cBarril() {
	if(this->fin ==  false)
	{
		this->fin = true;
		//std::cout <<"MUERE BARRIL: " << this->id << " (" << this->x << " , " << this->y << ")"<< std::endl;
		envioAlCliente::envioBorrarPersonaje(this->id, this->socket_J1, this->socket_J2);
	}
}

void cBarril::Desactivar()
{
	if(this->fin ==  false)
	{
		this->fin =  true;
		envioAlCliente::envioBorrarPersonaje(this->id, this->socket_J1, this->socket_J2);
	}
}

void cBarril::Inicializar(manejadorGrilla &grilla, int xMono, int yMono, int id, SocketCommunication *socket_J1, SocketCommunication *socket_J2) {
	//los barriles se crean donde esta el mono...
	sprintf(this->id, "bar_%d", id);
	this->type = objetosGrilla::getTypeBarril();
	this->fin = false;
	this->socket_J1 = socket_J1;
	this->socket_J2 = socket_J2;
	this->x = xMono + 3;
	this->y = yMono + 3;

	this->sentido = BUSCANDO_ESCALERA_INICIAL;
	if (this->getRandom() == 0)
		this->escaleraInicial = ESCALERA_INICIAL_1;
	else
		this->escaleraInicial = ESCALERA_INICIAL_2;

	envioAlCliente::envioCreacion(this->id, this->socket_J1, this->socket_J2, this->x, this->y);
	//envioAlCliente::envioPosicion(this->id, this->socket_J1, this->socket_J2, this->x, this->y);

}

//genera un un numero random del 1 al 10
int cBarril::getRandom() {
	this->nextRand = this->nextRand * 3 + time(NULL);
	srand(this->nextRand);

	//devuelve un numero entre 0 y 1
	return (rand() % 2);
}


void cBarril::mover(manejadorGrilla &grilla) {

	switch (this->sentido) {
	case BUSCANDO_ESCALERA_INICIAL: {
		if (this->x < this->escaleraInicial)
			this->x++;
		if (this->x > this->escaleraInicial)
			this->x--;
		if (this->x == this->escaleraInicial)
			this->sentido = BAJANDO_ESCALERA;
	}
		break;
	case IZQUIERDA: {
		//si se va de la pantalla y esta en la ultima linea termina
		if(this->x - 1< 0  && this->y == 43)
		{
			this->fin = true;
			//std::cout <<"MUERE BARRIL: " << this->id << " (" << this->x << " , " << this->y << ")"<< std::endl;
			envioAlCliente::envioBorrarPersonaje(this->id, this->socket_J1, this->socket_J2);
			return;
		}

		if (grilla.matriz[this->x - 1][this->y + 2] == 0) //evaluo si no hay piso...
				{
			if ((grilla.matriz[this->x - 5][this->y + 2] == 0) || (this->x - 5 <  0)) //esto es para darme cuenta si es un salto o termino el nivel y tiene que cambiar de sentido
			{
				this->sentido = DERECHA;
			} else {
				//tengo que saltar
				this->sentido = SALTANDO_IZQUERDA;
				this->saltoMovimiento = 1;
				this->x--;
				this->y--;
			}
		} else {
			//muevo
			this->x--;
			//despues de mover evaluo otras condiciones...

			//si hay escalera
			if (grilla.matriz[this->x][this->y + 4] == objetosGrilla::getTypeEscalera() 	&& grilla.matriz[this->x + 1][this->y + 4]== objetosGrilla::getTypeEscalera())
			{
				//hago un random indicando si la bajo o no...
				if (this->getRandom() == 0)
					this->sentido = BAJANDO_ESCALERA;  //bajo la escalera
				else
					this->sentido = IZQUIERDA;  //sigo moviendome a la izquierda
			}
		}
	}
		break;
	case DERECHA: {
		//si sale de la pantalla en el nivel inferior
		//si se va de la pantalla
		if(this->x + 3 > GRILLA_WIDTH  && this->y == 43)
		{
			this->fin = true;
			//std::cout <<"MUERE BARRIL: " << this->id << " (" << this->x << " , " << this->y << ")"<< std::endl;
			envioAlCliente::envioBorrarPersonaje(this->id, this->socket_J1, this->socket_J2);
			return;
		}

		if (grilla.matriz[this->x + 1][this->y + 2] == 0) //evaluo si no hay piso...
				{
			if ((grilla.matriz[this->x + 8][this->y + 2] == 0 ) || (this->x + 8 >  GRILLA_WIDTH)) //esto es para darme cuenta si es un salto o termino el nivel y tiene que cambiar de sentido
					{
				this->sentido = IZQUIERDA;
			} else {
				//tengo que saltar
				this->sentido = SALTANDO_DERECHA;
				this->saltoMovimiento = 1;
				this->x++;
				this->y--;
			}
		} else {
			//muevo
			this->x++;
			//despues de mover evaluo otras condiciones...

			//si hay escalera
			if (grilla.matriz[this->x][this->y + 4]	== objetosGrilla::getTypeEscalera() && grilla.matriz[this->x + 1][this->y + 4]	== objetosGrilla::getTypeEscalera()) {
				//hago un random indicando si la bajo o no...
				if (this->getRandom() == 0)
					this->sentido = BAJANDO_ESCALERA;  //bajo la escalera
				else
					this->sentido = DERECHA;   //sigo moviendome a la izquierda
			}
		}
	}
		break;
	case BAJANDO_ESCALERA: {
		this->y++;
		if (grilla.matriz[this->x][this->y + 2] == objetosGrilla::getTypePiso()) //si ya llego al piso
				{
			if (this->getRandom() == 0)
				this->sentido = IZQUIERDA;
			else
				this->sentido = DERECHA;
		}
	}
		break;
	case SALTANDO_DERECHA: {
		this->saltando(DERECHA);
	}
		break;
	case SALTANDO_IZQUERDA: {
		this->saltando(IZQUIERDA);
	}
		break;
	}
}

void cBarril::saltando(int sentido)
{
	switch (this->saltoMovimiento) {
		case 1:
			if(sentido == IZQUIERDA)
				this->x--;
			else
				this->x++;
			this->saltoMovimiento = 2;
			break;
		case 2:
			if(sentido == IZQUIERDA)
				this->x--;
			else
				this->x++;
			this->saltoMovimiento = 3;
			break;
		case 3:
			if(sentido == IZQUIERDA)
				this->x--;
			else
				this->x++;
			this->y++;
			this->saltoMovimiento = 4;
			break;
		case 4:
			if(sentido == IZQUIERDA)
				this->x--;
			else
				this->x++;
			this->saltoMovimiento = 0;
			this->sentido = sentido;
			break;
		default:
			this->sentido = sentido;
			this->saltoMovimiento = 0;
			break;
		}
}
